﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Microsoft.Office.Interop.Outlook;
using SNAIL.Classes;

namespace SNAIL
{
    public partial class Contact : Form
    {
        public Contact(Classes.Contact contact, Microsoft.Office.Interop.Outlook.Application app, ContactMessages ContactMessages)
        {
            InitializeComponent();
            this.Text = contact.DisplayString + " Email History";
            outlookapp = app;
            this.ReceivedFromMessages = ContactMessages.FromMessages;
            this.SentToMessages = ContactMessages.ToMessages;
            this.contact = contact;
        }

        private Classes.Contact contact;

        private List<ContactMessage> ReceivedFromMessages;
        private List<ContactMessage> SentToMessages;

        private Microsoft.Office.Interop.Outlook.Application outlookapp;

        private void Contact_Load(object sender, EventArgs e)
        {
            Dictionary<string, List<MailMessage>> Threads = new Dictionary<string, List<MailMessage>>();
            List<ContactMessage> RemoveInvalidIDs = new List<ContactMessage>();
            foreach (ContactMessage contactMessage in ReceivedFromMessages)
            {
                try
                {
                    MailMessage TempMessage = new MailMessage(((MailItem)outlookapp.Session.GetItemFromID(contactMessage.EntryID, null)), Direction.ReceivedFrom);
                    string ThreadID = TempMessage.MessageObject.ConversationIndex.Substring(0, 44);
                    //REPLACE UNRELIABLE CONVERSATION TOPIC INFORMATION WITH CONVERSATION INDEX EVALUATION
                    if (!Threads.ContainsKey(ThreadID))
                    {
                        Threads.Add(ThreadID, new List<MailMessage> { TempMessage });
                    }
                    else
                    {
                        Threads[ThreadID].Add(TempMessage);
                    }
                }
                catch (System.Runtime.InteropServices.COMException ex)
                {
                    if (ex.ErrorCode == -2147221233)
                    {
                        RemoveInvalidIDs.Add(contactMessage);
                    }
                }
            }
            foreach (ContactMessage item in RemoveInvalidIDs)
            {
                ReceivedFromMessages.Remove(item);
            }

            RemoveInvalidIDs = new List<ContactMessage>();

            foreach (ContactMessage contactMessage in SentToMessages)
            {
                try
                {
                    MailMessage TempMessage = new MailMessage(((MailItem)outlookapp.Session.GetItemFromID(contactMessage.EntryID, null)), Direction.SentTo);
                    string ThreadID = TempMessage.MessageObject.ConversationIndex.Substring(0, 44);
                    //REPLACE UNRELIABLE CONVERSATION TOPIC INFORMATION WITH CONVERSATION INDEX EVALUATION
                    if (!Threads.ContainsKey(ThreadID))
                    {
                        Threads.Add(ThreadID, new List<MailMessage> { TempMessage });
                    }
                    else
                    {
                        Threads[ThreadID].Add(TempMessage);
                    }
                }
                catch (System.Runtime.InteropServices.COMException ex)
                {
                    if (ex.ErrorCode == -2147221233)
                    {
                        RemoveInvalidIDs.Add(contactMessage);
                    }
                }
            }
            foreach (ContactMessage item in RemoveInvalidIDs)
            {
                ReceivedFromMessages.Remove(item);
            }

            SortedDictionary<DateTime, List<Thread>> DateAggregatedThreads = new SortedDictionary<DateTime, List<Thread>>();

            List<Thread> ThreadList = new List<Thread>();

            foreach (var Entries in Threads)
            {
                Thread TempThread = new Thread(Entries.Value);
                if (!DateAggregatedThreads.ContainsKey(TempThread.ThreadStartDateTime.Date))
                {
                    DateAggregatedThreads.Add(TempThread.ThreadStartDateTime.Date, new List<Thread> { TempThread });
                }
                else
                {
                    DateAggregatedThreads[TempThread.ThreadStartDateTime.Date].Add(TempThread);
                }
                ThreadList.Add(new Thread(Entries.Value));
            }

            foreach (var item in DateAggregatedThreads)
            {
                TreeNode DateNode = new TreeNode(item.Key.ToLongDateString());
                foreach (Thread thread in item.Value)
                {
                    TreeNode ThreadNode = new TreeNode(thread.ThreadStartDateTime.ToLongTimeString() + "-----TOPIC-----" + thread.ThreadTopic);
                    foreach (MailMessage message in thread.MessageObjects)
                    {
                        TreeNode MessageNode = new TreeNode();
                        MessageNode.Name = message.MessageObject.EntryID;
                        if (message.Direction == Direction.SentTo)
                        {
                            MessageNode.Text = "[SENT] " + message.ToString();
                        }
                        else if (message.Direction == Direction.ReceivedFrom)
                        {
                            MessageNode.Text = "[RECEIVED] " + message.ToString();
                        }
                        else
                        {
                            MessageNode.Text = message.ToString();
                            //SHOULD NOT OCCUR
                        }



                        //SOME KIND OF EMAIL MESSAGE PREVIEW HERE, STILL PROBLEMS WITH ENCODING
                        //if (message.MessageObject.Body.Length > 140)
                        //{
                        //    MessageNode.Nodes.Add(message.MessageObject.Body.Substring(0, 140));
                        //}
                        //else
                        //{
                        //    MessageNode.Nodes.Add(message.MessageObject.Body);
                        //}

                        ThreadNode.Nodes.Add(MessageNode);
                    }

                    DateNode.Nodes.Add(ThreadNode);
                }
                treeView1.Nodes.Add(DateNode);
            }


            OriginalState = treeView1.Nodes;

            //ThreadList.Sort(delegate(Thread t1, Thread t2)
            //{
            //    return t1.ThreadStartDateTime.CompareTo(t2.ThreadStartDateTime);
            //});

            //foreach (Thread TempThread in ThreadList)
            //{
            //    TreeNode ThreadNode = new TreeNode(TempThread.ThreadStartDateTime.ToString() + "-----TOPIC-----" + TempThread.ThreadTopic);

            //    foreach (MailMessage message in TempThread.MessageObjects)
            //    {
            //        ThreadNode.Nodes.Add(message.MessageObject.EntryID, message.ToString());
            //    }
            //    treeView1.Nodes.Add(ThreadNode);
            //}
        }

        private void treeView1_AfterSelect(object sender, TreeViewEventArgs e)
        {

        }

        private void treeView1_NodeMouseDoubleClick(object sender, TreeNodeMouseClickEventArgs e)
        {
            if (e.Node.Name.Length > 0)
            {
                ((MailItem)outlookapp.Session.GetItemFromID(e.Node.Name, null)).Display(false);
            }
        }

        TreeNodeCollection OriginalState;

        private void textBox1_TextChanged(object sender, EventArgs e)
        {
            if (textBox1.Text.Length > 0)
            {
                treeView2.Nodes.Clear();

                //REPLACE THIS UGLY CODE WITH RECURSIVE FUNCTION, WORKS SO FAR
                //EDIT: THIS IS A BIT BUGGY, AS THERE IS NO CHECK WHEATHER
                //CHILDREN NODES HAVE BEEN INCLUDED
                foreach (TreeNode Node in treeView1.Nodes)
                {
                    if (Node.Text.ToLowerInvariant().Contains(textBox1.Text.ToLowerInvariant()))
                    {
                        treeView2.Nodes.Add((TreeNode)Node.Clone());
                    }
                    foreach (TreeNode ChildNode in Node.Nodes)
                    {
                        if (ChildNode.Text.ToLowerInvariant().Contains(textBox1.Text.ToLowerInvariant()))
                        {
                            treeView2.Nodes.Add((TreeNode)ChildNode.Clone());
                        }
                    }
                }

                treeView1.Visible = false;
                treeView2.Visible = true;
            }
            else
            {
                treeView1.Visible = true;
                treeView2.Visible = false;
            }

        }

        private void button1_Click(object sender, EventArgs e)
        {
            textBox1.Text = "";
        }

        private void treeView2_MouseDoubleClick(object sender, MouseEventArgs e)
        {

        }

        private void treeView2_NodeMouseDoubleClick(object sender, TreeNodeMouseClickEventArgs e)
        {
            if (e.Node.Name.Length > 0)
            {
                ((MailItem)outlookapp.Session.GetItemFromID(e.Node.Name, null)).Display(false);
            }
        }
    }

    

    public enum Direction { SentTo, ReceivedFrom };
}
